package com.koylu.faces.onload;

import java.util.regex.Pattern;

import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Rule {

	private static Log logger = null;
	private String depends;
	private String method;
	private String view;
	private boolean navigate = false;
	private String action;
	private String bsh;

	public Rule() {
		logger = LogFactory.getLog(getClass());
	}

	private String viewPattern;

	public String getDepends() {
		return depends;
	}

	public void setDepends(String depends) {
		this.depends = depends;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getView() {
		return view;
	}

	public void setView(String view) {
		this.view = view;
	}

	public void setAction(String navigate, String action) {
		this.action = action;
		if ("true".equals(navigate)) {
			this.navigate = true;
		}
	}

	public boolean isNavigate() {
		return navigate;
	}

	public void setNavigate(boolean navigate) {
		this.navigate = navigate;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getBsh() {
		return bsh;
	}

	public void setBsh(String bsh) {
		this.bsh = bsh;
	}

	public boolean check(String view) {
		if (this.view == null) {
			return false;
		}
		if (viewPattern == null) {
			viewPattern = this.view;
			if (viewPattern.endsWith("*")) {
				viewPattern = viewPattern.replaceFirst("\\*",
						".\\*(.jsp|.jspx|.xhtml)\\$");
			}
		}
		return Pattern.compile(viewPattern).matcher(view).matches();
	}

	public void processRule(FacesContext ctx) {
		logger.info("view-->" + view);
		String formMethod = ((HttpServletRequest) ctx.getExternalContext()
				.getRequest()).getMethod();
		logger.info("formMethod-->" + formMethod);
		logger.info("method-->" + method);
		if(!StringUtils.isBlank(method)){
			if (!formMethod.equalsIgnoreCase(method)) {
				return;
			}
		}
		logger.debug("action-->" + action);
		if (!StringUtils.isBlank(action)) {
			MethodBinding method = ctx.getApplication().createMethodBinding(
					action, new Class[0]);
			if (method != null) {
				try {
					Object result = method.invoke(ctx, new Object[0]);
					logger.info("result-->" + result);
					logger.info("navigate-->" + navigate);
					if (navigate && result != null) {
						ctx.getApplication().getNavigationHandler()
								.handleNavigation(ctx, action,
										result.toString());
					}
				} catch (Exception e) {
					logger.error(e);
				}
			}
		}
		if (!StringUtils.isBlank(bsh)) {
			logger.info("interpreting bsh...");
			try {
				Class clazz = Class.forName("bsh.Interpreter");
				Object interpreter = clazz.newInstance();
				MethodUtils.invokeMethod(interpreter, "eval", bsh);
			} catch (Exception e) {
				logger.error(e);
			}
		}
	}

	public String toString() {
		return view;
	}
}
